import jwt
import datetime
from jwt import exceptions
from django.conf import settings
from rest_framework.authentication import BasicAuthentication
from rest_framework.exceptions import AuthenticationFailed


# 生成token
def create_token(payload):
    salt = settings.SECRET_KEY  # 盐
    print(payload)
    # 构造header

    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }

    # 构造payload
    payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(
        minutes=1440)  # 在payload字典中新加入一个exp信息，payload由函数传入;
    token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers)  # 生成jwt

    return token


# 解析token
class JwtQueryParamsAuthentication(BasicAuthentication):
    def authenticate(self, request):
        # 获取token并判断token的合法性
        # 1 切割
        # 2 解密第二段/判断是否过期
        # 3 验证第三段合法性

        token = request.headers.get('token')
        # print(token)
        salt = settings.SECRET_KEY  # 盐
        try:
            payload = jwt.decode(token, salt, True)  # 从token中获取payload，但是这个时候并没有校验合法性
        except exceptions.ExpiredSignatureError:
            raise AuthenticationFailed({'code': 1003, 'msg': 'token已失效'})
        except jwt.DecodeError:
            raise AuthenticationFailed({'code': 1003, 'msg': 'token认证失败'})
        except jwt.InvalidTokenError:
            raise AuthenticationFailed({'code': 1003, 'msg': '非法的token'})

        return (payload, token)

        # 三种操作
        # 1 抛出异常，后续不再执行
        # 2 return一个元组（1， 2），认证通过，在视图中如果调用request.user，就是元组的第一个值；如果调用request.auth，就是元组的第二个值
        # None，表示什么都不做，进行下一次认证
